'use strict';

const OSS = require('ali-oss');
const FormData = require('form-data');
const crypto = require('crypto');

// 初始化OSS客户端
const ossClient = new OSS({
    region: process.env.OSS_REGION,
    accessKeyId: process.env.OSS_ACCESS_KEY_ID,
    accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
    bucket: process.env.OSS_BUCKET,
});

/**
 * 云函数入口处理器
 * @param {Object} event - 事件对象
 * @param {Object} context - 上下文对象
 */
exports.handler = async (event, context) => {
    try {
        console.log('收到请求:', JSON.stringify(event, null, 2));
        
        // 解析请求体
        let body;
        if (event.body) {
            if (event.isBase64Encoded) {
                body = Buffer.from(event.body, 'base64').toString('utf8');
            } else {
                body = event.body;
            }
        }

        // 解析JSON或表单数据
        let requestData;
        const contentType = event.headers['content-type'] || event.headers['Content-Type'] || '';
        
        if (contentType.includes('application/json')) {
            requestData = JSON.parse(body);
        } else if (contentType.includes('multipart/form-data')) {
            requestData = await parseFormData(body, contentType);
        } else {
            throw new Error('不支持的Content-Type');
        }

        // 处理上传逻辑
        const result = await handleUpload(requestData);
        
        return {
            statusCode: 200,
            headers: {
                'Content-Type': 'application/json',
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Methods': 'POST, OPTIONS',
                'Access-Control-Allow-Headers': 'Content-Type',
            },
            body: JSON.stringify({
                success: true,
                message: '上传成功',
                data: result
            })
        };

    } catch (error) {
        console.error('处理请求失败:', error);
        
        return {
            statusCode: 500,
            headers: {
                'Content-Type': 'application/json',
                'Access-Control-Allow-Origin': '*',
            },
            body: JSON.stringify({
                success: false,
                message: error.message,
                error: error.stack
            })
        };
    }
};

/**
 * 处理文件上传逻辑
 * @param {Object} data - 上传数据
 */
async function handleUpload(data) {
    const results = [];
    
    // 支持单个文件或多个文件上传
    const files = data.files || (data.file ? [data.file] : []);
    
    for (const file of files) {
        try {
            const uploadResult = await uploadFileToOSS(file, data.options || {});
            results.push(uploadResult);
        } catch (error) {
            console.error(`上传文件失败: ${file.name || 'unknown'}`, error);
            results.push({
                success: false,
                file: file.name || 'unknown',
                error: error.message
            });
        }
    }
    
    return results;
}

/**
 * 上传文件到OSS
 * @param {Object} file - 文件对象
 * @param {Object} options - 上传选项
 */
async function uploadFileToOSS(file, options = {}) {
    const {
        folder = 'uploads',
        filename = null,
        contentType = 'application/octet-stream',
        metadata = {}
    } = options;

    // 生成文件名
    const originalName = filename || file.name || 'unknown';
    const fileExtension = originalName.includes('.') ? 
        originalName.substring(originalName.lastIndexOf('.')) : '';
    
    // 使用时间戳和随机数生成唯一文件名
    const timestamp = Date.now();
    const random = Math.random().toString(36).substring(2, 8);
    const uniqueFilename = `${timestamp}_${random}${fileExtension}`;
    
    // OSS对象键
    const objectKey = folder ? `${folder}/${uniqueFilename}` : uniqueFilename;
    
    // 准备上传选项
    const uploadOptions = {
        headers: {
            'Content-Type': contentType,
            ...metadata
        }
    };

    let result;
    
    // 根据文件类型选择上传方式
    if (file.buffer) {
        // Buffer形式上传
        result = await ossClient.put(objectKey, file.buffer, uploadOptions);
    } else if (file.base64) {
        // Base64形式上传
        const buffer = Buffer.from(file.base64.replace(/^data:.+;base64,/, ''), 'base64');
        result = await ossClient.put(objectKey, buffer, uploadOptions);
    } else if (file.url) {
        // URL形式上传（先下载再上传）
        const axios = require('axios');
        const response = await axios.get(file.url, { responseType: 'arraybuffer' });
        result = await ossClient.put(objectKey, response.data, uploadOptions);
    } else {
        throw new Error('不支持的文件格式');
    }

    // 生成访问URL
    const url = result.url || `https://${ossClient.options.bucket}.${ossClient.options.region}.aliyuncs.com/${objectKey}`;
    
    return {
        success: true,
        originalName,
        filename: uniqueFilename,
        objectKey,
        url,
        size: file.size || (file.buffer ? file.buffer.length : 0),
        contentType,
        uploadTime: new Date().toISOString()
    };
}

/**
 * 解析表单数据（简化版，实际项目中建议使用专业库）
 * @param {string} body - 请求体
 * @param {string} contentType - Content-Type
 */
async function parseFormData(body, contentType) {
    // 这里简化处理，实际项目中建议使用 multer 或 formidable 等库
    // 由于云函数环境的限制，这里提供基本的解析逻辑
    
    const boundary = contentType.match(/boundary=([^;]+)/)[1];
    const parts = body.split(`--${boundary}`);
    
    const data = { files: [] };
    
    for (const part of parts) {
        if (part.includes('Content-Disposition') && part.includes('filename=')) {
            // 提取文件信息
            const filenameMatch = part.match(/filename="([^"]+)"/);
            const nameMatch = part.match(/name="([^"]+)"/);
            
            if (filenameMatch) {
                const content = part.split('\r\n\r\n')[1].split('\r\n')[0];
                data.files.push({
                    name: nameMatch ? nameMatch[1] : 'file',
                    filename: filenameMatch[1],
                    buffer: Buffer.from(content, 'binary')
                });
            }
        }
    }
    
    return data;
}

/**
 * 生成STS临时凭证（用于前端直传）
 */
async function getSTSToken() {
    const STS = require('ali-oss').STS;
    
    const sts = new STS({
        accessKeyId: process.env.OSS_ACCESS_KEY_ID,
        accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
    });
    
    const result = await sts.assumeRole(
        `acs:ram::${process.env.ACCOUNT_ID}:role/OSSUploadRole`,
        ``,
        3600,
        'session'
    );
    
    return {
        accessKeyId: result.credentials.AccessKeyId,
        accessKeySecret: result.credentials.AccessKeySecret,
        securityToken: result.credentials.SecurityToken,
        expiration: result.credentials.Expiration
    };
}

/**
 * 处理OPTIONS请求（CORS预检）
 */
exports.handler.options = async (event, context) => {
    return {
        statusCode: 200,
        headers: {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'POST, OPTIONS',
            'Access-Control-Allow-Headers': 'Content-Type, Authorization',
            'Access-Control-Max-Age': '86400',
        },
        body: ''
    };
};